package fetcher

import (
	"bufio"
	"errors"
	"golang.org/x/net/html/charset"
	"golang.org/x/text/encoding"
	"golang.org/x/text/encoding/unicode"
	"golang.org/x/text/transform"
	"io/ioutil"
	"log"
	"net/http"
)

// 开启匹配.
func Start(url string) ([]byte, error) {
	if 0 == len(url) {
		return nil, errors.New("请求连接为空")
	}

	log.Printf("发起请求: %s.\n", url)

	response, err := http.Get(url)
	if nil != err {
		log.Printf("请求: %s, 出现错误.\n", url)
		return nil, err
	}
	body := response.Body
	defer body.Close()

	// 状态码判断.
	if response.StatusCode != http.StatusOK {
		log.Printf("请求: %s, 返回状态码: %d, 与预先准备的状态码: %d, 不匹配.\n",
			url,
			response.StatusCode,
			http.StatusOK)
		return nil, err
	}

	// 自动判断内容的编码.
	reader := bufio.NewReader(body)
	// 获取确定后的编码.
	determineEncoding := DetermineEncoding(err, reader, response)
	// 确定编码后的Reader.
	clearlyCodedReader := transform.NewReader(reader, determineEncoding.NewDecoder())
	return ioutil.ReadAll(clearlyCodedReader)
}

// 确定编码. 根据内容的前 1024 个字节的内容和声明的 Content-Type 来确定 HTML 文档的编码.
func DetermineEncoding(err error, reader *bufio.Reader, response *http.Response) encoding.Encoding {
	bytes, err := reader.Peek(1024)
	if nil != err {
		log.Printf("自动获取编码失败, 将使用默认的编码: %s.\n", unicode.UTF8)
		return unicode.UTF8
	}

	determineEncoding, _, _ := charset.DetermineEncoding(bytes, response.Header.Get("content-type"))
	return determineEncoding
}
